#pragma once

#include <iostream>
#include <string>

#include "util.hpp"

namespace ns_log
{
    using namespace ns_util;

    // 日志等级
    enum
    {
        INFO,
        DEBUG,
        WARNING,
        ERROR,
        FATAL
    };

    // 封装日志消息
    // 用法：LOG(level) << message <<"\n";（开放式日志，\n刷新缓冲区）
    // 日志格式：[level][file_name][line][time] message
    // 因为日志使用频繁，宏替换也频繁，函数调用频繁，用 inline 减少函数调用的开销
    inline std::ostream &log(const std::string &level, const std::string &file_name, int line)
    {
        std::string message;

        // 日志等级
        message += '[';
        message += level;
        message += ']';

        // 代码所在的文件名
        message += '[';
        message += file_name;
        message += ']';

        // 代码所在行
        message += '[';
        message += std::to_string(line);
        message += ']';

        message += '[';
        message += TimeUtil::GetTimeStamp();
        message += ']';

        // 返回标准输出流
        // cout 有缓冲区，将 [level][file_name][line][time] 写入 cout 中
        std::cout << message;

        // 日志消息结尾先不加换行符，暂时不刷新缓冲区
        // [level][file_name][line][time] 会暂存在 cout 中

        return std::cout;
    }

    // #level 可以把日志等级从数字转为对应的字符串
    // __FILE__, __LINE__ 在编译时替换成对应的文件名和行数
    #define LOG(level) log(#level, __FILE__, __LINE__)
}